#include "SFC_Inc.hpp"
#include "SFC_Window.h"
#include "SFC_WindowServer.h"
#include "Trace.h"

extern SFC_WindowServer *WindowManager;

SFC_Window::SFC_Window()
{
	this->Children.push_back(&this->TitleBar);
	this->Children.push_back(&this->CloseButton);
	this->Children.push_back(&this->Container);

	this->TitleBar.Color = 0x3333EE;
	this->TitleBar.FrontColor = 0xFFFFFF;
	this->TitleBar.Transform = false;
	this->TitleBar.Parent = this;
	
	this->CloseButton.Parent = this;
	this->CloseButton.OnClick += { this, &SFC_Window::Close };
}

SFC_Window::~SFC_Window()
{
}

void SFC_Window::StartListen()
{
	while (this->Runable)
	{
		SFC_Event event = this->MsgQueue.Get();
		EventRouter(event);
	}
	trace << "Window listen thread is quit." << std::endl;
}

void SFC_Window::EventRouter(SFC_Event &Event)
{
	if (this->CloseButton.Size.Inside(Event.Forcus)) {
		this->CloseButton.EventRouter(Event);
	} else if (this->TitleBar.Size.Inside(Event.Forcus)) {
		this->TitleBar.EventRouter(Event);
	} else if (Event.Type == EventType::Window && Event.Window.Type == WindowEventType::Paint) {
		Paint();
	}
}

void SFC_Window::LoadRes()
{
	this->TitleBar.Text = Title;
	this->TitleBar.Size = {1, 1, this->Size.w - 2, this->TitleBarHgt};

	this->CloseButton.Text = "X";
	this->CloseButton.Size = {this->Size.w - this->TitleBarHgt + 1, 3, this->TitleBarHgt - 4, this->TitleBarHgt - 4};

	this->Container.Size = {1, this->TitleBarHgt + 2, this->Size.w - 2, this->Size.h - this->TitleBarHgt - 3};

	// Create cache surface
	if (this->Cache == nullptr)
		this->Cache = CreateSurface(this->Size.w, this->Size.h);
	FillRect(this->Cache, nullptr, 0xFFFFFF);
}

void SFC_Window::Show()
{
	LoadRes();
	WindowManager->AddWindow(this);
}

bool SFC_Window::Close()
{
	this->Runable = this->Visiable = false;
	
	SFC_Event CloseEvent;
	CloseEvent.Type = EventType::Window;
	CloseEvent.Window.Type = WindowEventType::Closing;
	this->MsgQueue.Put(CloseEvent);
	
	WindowManager->RemoveWindow(this);
	return 0;
}

void SFC_Window::Paint()
{
	if (this->Durty == false) return ;
	
	// trace << "Paint Window" << std::endl;
	LoadRes();
	// Draw frame
	SFC_Rect rect = {0, 0, this->Size.w, this->Size.h};
	DrawRect(this->Cache, &rect, 0x000000);
	// Draw split line
	DrawLine(this->Cache, 0, this->TitleBarHgt, this->Size.w, this->TitleBarHgt, 0x000000);
	this->Durty = false;
}